﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using LogikBug.ModularMvc.Attributes;

namespace LogikBug.ModularMvc
{
	public static class AssemblyExtensions
	{
		private static string _moduleName = typeof (IModule).Name;

		#region Methods

		public static IModule GetMvcModule(this Assembly assembly)
		{
			var moduleType = assembly.ThrowIfNull().GetExportedTypes().SingleOrDefault(t => t.GetInterface(_moduleName, true) != null);

			if (IsValidModuleType(moduleType))
			{
				return (IModule)Activator.CreateInstance(moduleType);
			}

			return null;
		}

		public static IEnumerable<IModule> GetMvcModules(this Assembly assembly)
		{
			return (from moduleType in assembly.ThrowIfNull().GetExportedTypes().Where(t => t.GetInterface(_moduleName, true) != null)
			        where IsValidModuleType(moduleType)
			        select (IModule) Activator.CreateInstance(moduleType)).ToList();
		}

		public static IEnumerable<IModule> GetMvcModules(this IEnumerable<RegisterModuleAttribute> attributes)
		{
			foreach (var attribute in attributes.ThrowIfNull())
			{
				var moduleType = attribute.ModuleType;

				if (!IsValidModuleType(moduleType)) { continue; }

				yield return (IModule)Activator.CreateInstance(moduleType);
			}

			yield return null;
		}

		private static bool IsValidModuleType(Type type)
		{
			return type != null && !type.IsAbstract && !type.IsInterface;
		}

		#endregion
	}
}
